package cn.flying.cloud.base.common.utils.crypto;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;

/**
 * Cipher 密码工具类
 *
 * @author: admin
 * @date: 2025年01月23日 09:54
 * @version: 1.0
 */
public class CipherUtils {

    /**
     * 生成密钥
     *
     * @param keySeed
     * @param algorithm
     * @param keySize
     * @return
     * @throws Exception
     */
    public static String generateKey(String keySeed, String algorithm, int keySize) throws Exception {
        if (keySeed == null || keySeed.trim().isEmpty()) {
            keySeed = UUID.randomUUID().toString().replaceAll("-", "");
        }
        KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
        SecureRandom random = new SecureRandom(keySeed.getBytes(StandardCharsets.UTF_8));
        keyGen.init(keySize, random);
        SecretKey secretKey = keyGen.generateKey();
        return Base64.getEncoder().encodeToString(secretKey.getEncoded());
    }

    /**
     * 加密
     *
     * @param data      被加密的内容
     * @param secret    密钥文本
     * @param algorithm 密码模式
     * @param padding   填充模式
     * @return 加密好的内容(base64)
     */
    public static String encrypt(String data, String secret, String algorithm, String padding) throws Exception {
        SecretKey secretKey = secretKey(secret, algorithm);
        byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
        Cipher cipher = Cipher.getInstance(padding);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] bytes = cipher.doFinal(dataBytes);
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 解密
     *
     * @param cipherText 密文(base64)
     * @param secret     密钥
     * @param algorithm  密码模式
     * @param padding    填充模式
     * @return 解密好的内容
     */
    public static String decrypt(String cipherText, String secret, String algorithm, String padding) throws Exception {
        SecretKey secretKey = secretKey(secret, algorithm);
        byte[] cipherBytes = Base64.getDecoder().decode(cipherText);
        Cipher cipher = Cipher.getInstance(padding);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] bytes = cipher.doFinal(cipherBytes);
        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 生成密钥对象 - 用于根据密钥文本创建密钥对象进行数据加解密。
     *
     * @param key 密钥文本
     * @return 密钥对象
     */
    private static SecretKey secretKey(String key, String algorithm) {
        byte[] bytes = Base64.getDecoder().decode(key);
        return new SecretKeySpec(bytes, algorithm);
    }
}
